<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      //  2、给myReduce绑定在数组原型链下面
      Array.prototype.myReduce = function (fn, initValue) {
        // 3、判断fn传入的是不是函数
        if (Object.prototype.toString.call(fn) !== '[object Function]') {
          // 4、不是就抛出一个错误
          throw new Error('current params in not correct')
        }
        let arr = this
        // 5、根据initValue是否有传入来决定myReduce方法的数组是从哪一项开始循环，累加的值是第一项还是传入的值
        let initIndex //存放数组是从第一项遍历 还是第二项遍历
        let acc // 累加器
        // arguments 传入的参数列表
        // 如果我们没有传入第二个参数，数组会从下标为1的一项循环，如果传入了第二个参数，数组会从下标为0的一项循环
        initIndex = arguments.length === 1 ? 1 : 0
        //初始值
        acc = arguments.length === 1 ? arr[0] : initValue
        for (let i = initIndex; i < arr.length; i++) {
          acc = fn(acc, arr[i], i, arr)
        }
        return acc
      }

      const arr = [1, 2, 3]
      // 1、 reduce 可以传入两个参数 第一个是函数 第二个是初始值
      const res = arr.myReduce((pre, cur) => {
        return pre + cur
      })
      console.log(res)
    </script>
  </body>
</html>
